package main

import (
	"fmt"
)

func main() {
	/*
		1.Go 中的字符串是一个字节的切片
			可以通过将其内容封装在""中来创建字符串，G0 中的字符串是 Unicode 兼容的，并且是 UTF-8 编码的

		2.字符串是一些字节的集合
			理解为一个字符的序列
			每个字符都有固定的位置（索引，下标，index：从 0 开始，到长度减 1）

		3.语法："", ``
			""中的字符串可以转义，但是不能换行
			``中的字符串不会被转义，可以换行（换行将被当做是字符串中的换行）

			转义字符：
				1.无法被键盘录入的字符
					例如：响铃符(\a)、退格符(\b)、换行符(\n)、回车符(\r)、水平制表符(\t)、垂直制表符(\v)、
						双引号（\"）、单引号（\'）、反斜杠（\\）...
				2.被当做特殊用途而需要转换回它原来的意义的字符

		4.字符：——> 对应编码表中的编码值
			A ——> 65
			B ——> 66
			a ——> 97
			...

		5.字节：byte ——> Uint8
				UTF-8 //中文占 3~4 个字节

		注：
			1.字符有以下两种：
			（1）uint8 类型，或者叫 byte 类型，代表一个 ASCII码 字码
			（2）int32 类型，或者叫 rune 类型，代表一个 UTF-8 字符
				当需要处理中文、日文或者其他复合字符时，则需要用到 rune 类型。

			2.字符串的底层是一个 byte 数组，可以和 []byte 类型相互转换。
			rune 类型 用来表示 UTF-8 字符，一个 rune 字符由一个或多个 byte 组成。

			3.字符串是不能被修改的，字符串是由 byte 字节租场，所以字符串的长度是 byte字节 的长度。

			4.修改字符串，需要先将其转换成 []byte 或 []rune，完成后再转换为 string。
			无论哪种转换，都会重新分配内存，并复制字节数组。
	*/
	//1.定义字符串
	s1 := "hello中国"
	s2 := "hello world"
	fmt.Println(s1)
	fmt.Println(s2)

	//2.字符串的长度
	// len() 的返回值是字节的个数，而不是字符的个数
	fmt.Println(len(s1)) //11
	fmt.Println(len(s2)) //11

	//3.获取某个字符
	fmt.Println(s2[0]) //104  获取字符串中的第一个字节
	a := 'h'
	b := 104
	fmt.Printf("%c,%c,%c\n", s2[0], a, b) //h,h,h

	//4.字符串的遍历
	for i := 0; i < len(s1); i++ { // 按照字节打印
		fmt.Printf("%c ", s1[i])
	} //h e l l o ä ¸ ­ å
	//打印中文乱码是因为中文是三个字节存储一个中文字，不能按照字节打印
	fmt.Println()

	for _, v := range s2 {
		fmt.Printf("%c", v)
	}
	fmt.Println()

	//5.字符串是字节的集合（字符串 与 切片的相互转换）
	slice1 := []byte{65, 66, 67, 68, 69}
	s3 := string(slice1) // 根据一个字节切片，构建字符串
	fmt.Println(s3)

	s4 := "abcde"
	slice2 := []byte(s4) // 根据字符串，获取对应的字节切片
	fmt.Println(slice2)

	//6.字符串不能修改
	fmt.Println(s4)
	//s4[2] = 'B'// cannot assign to s4[2] (value of type byte)

	//""中的字符串可以转义，但是不能换行
	//``中的字符串不会被转义，可以换行
	xx := "hello\a"
	xxx := `hello\a`
	xxxx := `Hel
lo`
	fmt.Println(xx)
	fmt.Println(xxx)
	fmt.Println(xxxx)
	/*结果：
	hello（电脑发出一声响声）
	hello\a
	Hel
	lo
	*/
}
